// Copyright (C) 2012 Tanmay Sinha.
// All rights reserved

package org.saakshar;

import static org.saakshar.utils.StringUtils.*;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.saakshar.content.ContentRetriever;
import org.saakshar.content.Label;
import org.saakshar.content.Post;
import org.saakshar.content.blogger.BloggerJsonContentLoaderV2;
import org.saakshar.content.blogger.BloggerJsonContentRetrieverV2;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ScrollView;
import android.widget.SimpleExpandableListAdapter;

/**
 * Activity to display the articles
 * 
 * @author tanmay
 * 
 */
public class ReaderActivity extends Activity implements OnInitListener {

	/** The Tag */
	private static final String TAG = ReaderActivity.class.getSimpleName();

	private static final int DIALOG_WORD_DEFINTION = 1;
	private static final String EXPANDABLE_LIST_NAME_CONSTANT = "name";
	private static final String EXPANDABLE_LIST_ID_CONSTANT = "id";

	private ExpandableListView articlesList;
	private ReaderTextView articleText;

	private String selectedText;
	private String definition;

	private static Spanned currentArticle;
	private static boolean articleListVisible = true;
	private static TextToSpeech tts;
	private static ContentRetriever contentRetriever;
	private final List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();

	private final OnChildClickListener articleListItemClickListener = new OnChildClickListener() {

		@Override
		public boolean onChildClick(ExpandableListView parent, View v,
				int groupPosition, int childPosition, long id) {

			String postId = childData.get(groupPosition).get(childPosition)
					.get(EXPANDABLE_LIST_ID_CONSTANT);

			if (!isBlank(postId)) {
				Post post = contentRetriever.getPost(postId);

				if (post != null) {
					currentArticle = Html.fromHtml(post.getContent(), null,
							null);
					articleText.setText(currentArticle);
					makeArticleListVisible(false);
				}
			}
			return true;
		}
	};

	/** Called when the activity is first created. */

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		if (tts == null) {
			tts = new TextToSpeech(this, this);
		}

		if (contentRetriever == null) {
			retrieveContent();
		}

		setContentView(R.layout.reader_layout);

		articleText = (ReaderTextView) findViewById(R.id.articleText);
		registerForContextMenu(articleText);

		if (currentArticle != null) {
			articleText.setText(currentArticle);
		}

		articlesList = (ExpandableListView) findViewById(R.id.articlesList);

		final ScrollView scrollView = (ScrollView) findViewById(R.id.articlesScrollView);
		scrollView.setSmoothScrollingEnabled(true);
		scrollView.post(new Runnable() {
			@Override
			public void run() {
				scrollView.fullScroll(ScrollView.FOCUS_UP);
			}
		});

		makeArticleListVisible(articleListVisible);

		articlesList.setOnChildClickListener(articleListItemClickListener);

		reloadArticlesList();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);

		int startSelection = articleText.getSelectionStart();
		int endSelection = articleText.getSelectionEnd();

		selectedText = articleText.getText()
				.subSequence(startSelection, endSelection).toString();

		if (v.getId() == R.id.articleText) {
			if (!isBlank(selectedText) && isAWord(selectedText)) {
				menu.add(Menu.NONE, R.id.save_word, Menu.NONE, "Save \""
						+ selectedText + "\"");
				menu.add(Menu.NONE, R.id.read_word, Menu.NONE, "Read \""
						+ selectedText + "\"");
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.reader_activity_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.articles_list_menu_item:
			switch (articlesList.getVisibility()) {
			case View.VISIBLE:
				makeArticleListVisible(false);
				break;
			case View.GONE:
				makeArticleListVisible(true);
				break;
			}
			break;
		case R.id.sight_words_menu_item:
			Intent intent = new Intent(this, WordsActivity.class);
			startActivity(intent);
			break;
		case R.id.reload_articles_menu_item:
			retrieveContent();
			reloadArticlesList();
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {

		int selectedItem = item.getItemId();

		switch (selectedItem) {
		case R.id.read_article:
			tts.speak(articleText.getText().toString(), TextToSpeech.QUEUE_ADD,
					null);
			break;
		case R.id.read_word:
			tts.speak(selectedText, TextToSpeech.QUEUE_FLUSH, null);
			break;
		case R.id.save_word:
			try {
				FileOutputStream fos = openFileOutput(
						getString(R.string.my_word_file_name),
						Context.MODE_APPEND);
				String writeLine = selectedText + "\n";
				fos.write(writeLine.getBytes());
				fos.close();
			} catch (FileNotFoundException e) {
				Log.e(TAG, "Could not find the file.", e);
			} catch (IOException e) {
				Log.e(TAG, "Exception when writing to the file.", e);
			}

			break;
		default:
			break;

		}
		return super.onContextItemSelected(item);
	}

	@Override
	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {
			tts.setLanguage(Locale.US);
		} else {
			Log.e(TAG, "Could not initialize TextToSpeech.");
		}

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		if (tts != null) {
			tts.shutdown();
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		super.onCreateDialog(id);
		Dialog dialog;
		switch (id) {
		case DIALOG_WORD_DEFINTION:

			dialog = new AlertDialog.Builder(this)
					.setMessage(getDialogMessage()).setCancelable(true)
					.create();
			break;
		default:
			dialog = null;
		}
		return dialog;

	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		super.onPrepareDialog(id, dialog);

		switch (id) {
		case DIALOG_WORD_DEFINTION:
			((AlertDialog) dialog).setMessage(getDialogMessage());
			break;
		default:
			break;

		}
	}

	private void reloadArticlesList() {

		List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();

		for (Label label : contentRetriever.getLabels()) {
			Map<String, String> currentGroupMap = new HashMap<String, String>();
			groupData.add(currentGroupMap);
			currentGroupMap
					.put(EXPANDABLE_LIST_NAME_CONSTANT, label.getLabel());

			List<Map<String, String>> children = new ArrayList<Map<String, String>>();
			List<Post> posts = contentRetriever.getPosts(label);

			if (posts != null) {
				for (Post post : contentRetriever.getPosts(label)) {
					Map<String, String> currentChildMap = new HashMap<String, String>();
					children.add(currentChildMap);
					currentChildMap.put(EXPANDABLE_LIST_NAME_CONSTANT,
							post.getTitle());
					currentChildMap.put(EXPANDABLE_LIST_ID_CONSTANT,
							post.getId());
				}
			}
			childData.add(children);
		}

		SimpleExpandableListAdapter simpleExpandableListAdapter = new SimpleExpandableListAdapter(
				this, groupData,
				android.R.layout.simple_expandable_list_item_1,
				new String[] { EXPANDABLE_LIST_NAME_CONSTANT },
				new int[] { android.R.id.text1 }, childData,
				android.R.layout.simple_expandable_list_item_2,
				new String[] { EXPANDABLE_LIST_NAME_CONSTANT },
				new int[] { android.R.id.text1 });
		articlesList.setAdapter(simpleExpandableListAdapter);

	}

	private void retrieveContent() {
		try {
			contentRetriever = new BloggerJsonContentRetrieverV2(
					getString(R.string.blogger_api_key),
					getString(R.string.blog_id));
			BloggerJsonContentLoaderV2 bloggerJsonContentLoaderV2 = new BloggerJsonContentLoaderV2();
			bloggerJsonContentLoaderV2.execute(contentRetriever);
			bloggerJsonContentLoaderV2.get();
		} catch (InterruptedException e) {
			Log.e(TAG, "Content retrieval interrupted.");
		} catch (ExecutionException e) {
			Log.e(TAG, "Content retrieval failed.");
		}
	}

	private String getDialogMessage() {
		String message;
		if (isBlank(definition)) {
			message = "Could not find the meaning for \"" + selectedText
					+ "\".";
		} else {
			message = selectedText + "\n\n" + definition;
		}

		return message;
	}

	private void makeArticleListVisible(boolean visible) {
		articleListVisible = visible;
		if (visible) {
			articlesList.setVisibility(View.VISIBLE);
		} else {
			articlesList.setVisibility(View.GONE);
		}
	}
}